package com.koron.sinoprobe.web.plan.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.bean.workflow.RedirectQuery;
import com.koron.common.core.business.workflow.service.SysWorkflowService;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.interceptor.OrderByInterceptor;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.OrgCacheUtils;
import com.koron.sinoprobe.config.Constants;
import com.koron.sinoprobe.web.common.CommonUtils;
import com.koron.sinoprobe.web.plan.bean.entity.SpPlanPackage;
import com.koron.sinoprobe.web.plan.bean.query.SpPlanPackageQuery;
import com.koron.sinoprobe.web.plan.bean.query.SpPlanQuery;
import com.koron.sinoprobe.web.plan.bean.vo.SpPlanPackageVO;
import com.koron.sinoprobe.web.plan.bean.vo.SpPlanVO;
import com.koron.sinoprobe.web.plan.mapper.SpPlanPackageMapper;
import com.koron.sinoprobe.web.plan.service.SpPlanPackageService;
import com.koron.sinoprobe.web.plan.service.SpPlanService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author twcao
 * @title: SpPlanPackageServiceImpl
 * @projectName GDH_EAM_V2
 * @description: 专项计划包service实现
 * @date 2021/11/2417:07
 */
@Slf4j
@Service
public class SpPlanPackageServiceImpl implements SpPlanPackageService {

    @Autowired
    private SpPlanService planService;

    @Autowired
    private SysWorkflowService sysWorkflowService;

    @Autowired
    private OrgCacheUtils orgCacheUtils;

    @Override
    @TaskAnnotation("selectOne")
    public SpPlanPackageVO selectOne(SessionFactory factory, String pkgId) {
        SpPlanPackageMapper mapper = factory.getMapper(SpPlanPackageMapper.class);
        SpPlanPackageVO spPlanPackageVO = mapper.queryById(pkgId);
        // 根据组织分组查询
        List<Map<String, Object>> maps = groupByPkgId(factory, pkgId);
        spPlanPackageVO.setDeptList(maps);
        return spPlanPackageVO;
    }

    @Override
    @TaskAnnotation("queryList")
    public List<SpPlanPackageVO> queryList(SessionFactory factory, SpPlanPackageQuery query) {
        SpPlanPackageMapper mapper = factory.getMapper(SpPlanPackageMapper.class);
        List<SpPlanPackageVO> pkgs = mapper.queryList(query);
        pkgs.stream().forEach(row -> row.setDeptName(orgCacheUtils.getOrgNameById(row.getDeptId())));
        return pkgs;
    }

    @Override
    @TaskAnnotation("queryPlanList")
    public List<SpPlanVO> queryPlanList(SessionFactory factory, SpPlanQuery query) {
        Assert.isTrue(query != null && StringUtils.isNotEmpty(query.getPkgId()), "计划包id不能为空");
        SpPlanPackageVO pkg = selectOne(factory, query.getPkgId());
        Assert.isTrue(pkg != null && !pkg.getDeleteFlag(), "计划包不存在");
        OrderByInterceptor.setOrderBy(query.getOrders());
        PageHelper.startPage(query.getPage(), query.getPageSize());
        query.setDeleteFlag(null);
        return planService.queryList(factory, query);
    }

    @Override
    @TaskAnnotation("groupByPkgId")
    public List<Map<String, Object>> groupByPkgId(SessionFactory factory, String pkgId) {
        Assert.isTrue(StringUtils.isNotEmpty(pkgId), "计划包id不能为空");
        return planService.groupByPkgId(factory, pkgId);
    }

    @Override
    @TaskAnnotation("getPlanById")
    public SpPlanVO getPlanById(SessionFactory factory, String planId) {
        return planService.selectOne(factory, planId);
    }

    @Override
    @TaskAnnotation("deletePlanById")
    public Boolean deletePlanById(SessionFactory factory, String planId) {
        planService.deleteById(factory, planId);
        // 删除计划包的工作流
        sysWorkflowService.deleteByDataId(planId);
        return true;
    }

    @Override
    @TaskAnnotation("saveOrUpdate")
    public SpPlanPackageVO saveOrUpdate(SessionFactory factory, SpPlanPackageVO detail) {
        Assert.notNull(detail, "专项计划包不能为空");
        SpPlanPackage pkg = saveOrUpdate(factory, (SpPlanPackage) detail);
        SpPlanVO plan = detail.getPlan();
        if(Objects.isNull(plan)) {
            return detail;
        }
        plan.setPkgId(pkg.getId());
        plan.setDeptId(pkg.getDeptId());
        // 默认设置为已删除（即不可用），若计划包未审核通过，改计划不允许在计划列表展示
        plan.setDeleteFlag(true);
        // 计划包生成
        plan.setPlanSource(Constants.PlanSource.PLAN_PACKAGE);
        // 计划跟计划包同步走流程
        plan.setAssistStatus(Constants.PlanAssistStatus.SYNC);
        planService.saveOrUpdate(factory, plan);
        return detail;
    }

    @Override
    public SpPlanPackage saveOrUpdate(SessionFactory factory, SpPlanPackage bean) {
        SpPlanPackageMapper mapper = factory.getMapper(SpPlanPackageMapper.class);
        EamUser user = ThreadLocalContext.get();
        CommonUtils.update(bean);
        CommonUtils.update(bean, user);
        bean.setId(StringUtils.isBlank(bean.getId()) ? CodeTools.getCode32() : bean.getId());
        bean.setDeptId(StringUtils.isBlank(bean.getDeptId()) ? user.getOrgId() : bean.getDeptId());
        bean.setCode(StringUtils.isBlank(bean.getCode()) ? CommonUtils.getCodeNo(Constants.SPP_PREFIX_CODE, null, "yyyy",3) : bean.getCode());
        bean.setStatus(StringUtils.isBlank(bean.getStatus()) ? Constants.PackageStatus.DRAFT : bean.getStatus());
        planService.updateStatus(factory, bean.getId(), bean.getStatus());
        mapper.saveOrUpdate(bean);
        return bean;
    }

    @Override
    @TaskAnnotation("submit")
    public SpPlanPackageVO submit(SessionFactory factory, SpPlanPackageVO detail) {
        // 状态设置为待审核
        detail.setStatus(Constants.PackageStatus.WAIT_REVIEW);
        planService.updateStatus(factory, detail.getId(), Constants.PackageStatus.WAIT_REVIEW);
        // 1、保存专项计划包
        saveOrUpdate(factory, detail);
        // 2、创建工作流
        /*List<SysWorkflow> sysWorkflows = workflowService.queryByDataId(detail.getId());
        if(!CollectionUtils.isEmpty(sysWorkflows)) {
            return detail;
        }
        // 指定下个节点审批人id
        Map<String, String> formVariables = new HashMap<>(2);
        WorkflowProperties prop = WorkflowProperties.init(Constants.SP_PACKAGE_WORKFLOW.PROCESS_CODE);
        SysWorkflow workflow = workFlowHandler.start(prop, detail.getId(), detail.getCode(), formVariables);
        log.info("工作流创建成功， billId = {}", workflow.getBillId());*/
        return detail;
    }

    @Override
    @TaskAnnotation("auditFinish")
    public SpPlanPackageVO auditFinish(SessionFactory factory, SpPlanPackageVO detail) {
        Assert.isTrue(detail != null && !StringUtils.isEmpty(detail.getId()), "计划包id不能为空");
        // 工作流结束后，专项计划包设置为已审批
        detail.setStatus(Constants.PackageStatus.APPROVED);
        planService.updateStatus(factory, detail.getId(), Constants.PackageStatus.APPROVED);
        List<SpPlanVO> plans = planService.getByPkgId(factory, detail.getId());
        // 如果专项计划包审核通过，则计划包内的计划不需要再审核，设置为已审核状态，并与计划包共用审批流
        plans.stream().forEach(plan -> {
            // 1、更新工作流状态
            plan.setStatus(Constants.PlanStatus.APPROVED);
            plan.setCode(StringUtils.isEmpty(plan.getCode()) ? CommonUtils.getCodeNo(Constants.SP_PREFIX_CODE, null, 3) : plan.getCode());
            // 审核完成，可以在计划列表展示
            plan.setDeleteFlag(false);
            planService.update(factory, plan);
            log.info("专项计划包生成专项计划： {}", JSON.toJSONString(plan));
        });
        saveOrUpdate(factory, detail);
        return detail;
    }

    @Override
    @TaskAnnotation("deleteById")
    public String deleteById(SessionFactory factory, String pkgId) {
        SpPlanPackageMapper mapper = factory.getMapper(SpPlanPackageMapper.class);
        // 删除计划包内的计划（含工作流）
        planService.hiddenByPkgId(factory, pkgId);
        mapper.hiddenById(pkgId);
        // 删除计划包的工作流
        sysWorkflowService.deleteByDataId(pkgId);
        return pkgId;
    }

    @Override
    @TaskAnnotation("workflowUpdate")
    public Boolean workflowUpdate(SessionFactory factory, RedirectQuery redirectQuery) {
        Integer operation = redirectQuery.getOperation();
        SpPlanPackageVO vo = JSON.parseObject(redirectQuery.getFormVariables(), SpPlanPackageVO.class);
        SpPlanPackageMapper mapper = factory.getMapper(SpPlanPackageMapper.class);
        switch (operation) {
            case 256: // 撤回
            case 1: // 驳回
                // 驳回的节点编号
                vo.setStatus(Constants.PackageStatus.DRAFT);
                planService.updateStatus(factory, vo.getId(), Constants.PackageStatus.DRAFT);
                //saveOrUpdate(factory, vo);
                break;
            case 32: // 同意
                vo.setStatus(Constants.PackageStatus.WAIT_REVIEW);
                planService.updateStatus(factory, vo.getId(), Constants.PackageStatus.WAIT_REVIEW);
                //saveOrUpdate(factory, vo);
                break;
        }
        // 更新状态
        mapper.updateStatusById(vo.getId(), vo.getStatus());
        return true;
    }
}
